HDFS概述及设计目标
如果让我们自己来设计一个分布式文件系统,咋办?
下图是普通分布式文件系统
什么是HDFS
- Hadoop实现了一个分布式文件系统( Hadoop Distributed File System) ,简称HDFS
- 源自Google的GFS论文
- 发表于2003年,HDFS是GFS的克隆版
- 基于JAVA实现的一个分布式文件系统
- 基于unix/linux
- 是Hadoop最重要的核心组件
- 支持顺序写入,而非随机定位读写
HDFS前提和设计目标
- 存储超大文件
HDFS适合存储大文件,单个文件大小通常在百MB以上
HDFS适合存储海量文件,总存储量可达PB,EB级 - 硬件容错
基于普通机器搭建,硬件错误是常态而不是异常,因此错误检测和快速、自动的恢复是HDFS最核心的架构目标 - 流式数据访问
为数据批处理而设计,关注数据访问的高吞吐量 - 简单的一致性模型
一次写入,多次读取
一个文件经过创建、写入和关闭之后就不需要改变 - 本地计算
将计算移动到数据附近
HDFS 构成及工作原理解析
基本构成
- 数据块
- 文件以块为单位进行切分存储,块通常设置的比较大(最小6M,默认128M)
- 块越大,寻址越快,读取效率越高,但同时由于MapReduce任务也是以块为最小单位来处理,所以太大的块不利于于对数据的并行处理
- 一个文件至少占用一个块(逻辑概念)
- Namenode与Datanode
- namenode 负责维护整个文件系统的信息,包括:整个文件树,文件的块分布信息,文件系统的元数据,数据复制策略等
- datanode 存储文件内容,负责文件实际的读写操作,保持与namenode的通信,同步文件块信息
1 | 一个文件有多少个块:文件大小/块的大小 |
数据读写过程
文件写流程
hadoop fs -put xxx.log /
写过程是对客户端无感知的
FSDataOutputStream
- Client调用FileSystem.create(filePath)方法,与NN进行【rpc】通信,检查其是否存在及是否有权限创建;假如不ok,就返回错误信息;假如ok,就创建一个新文件,不关联任何的block块,返回一个FSDataOutputStream对象。
- Client调用FSDataOutputStream对象的write()方法,先将第一块的第一个副本的一个packet写到第一个DN,第一个副本写完;就传输给第二个DN,第二个副本写完;就传输给第三个DN,第三个副本写完。
- 就返回一个ack packet确认包给第二个DN,第二个DN接收到第三个的ack packet确认包加上自身ok,就返回一个ack packet确认包给第一个DN,第一个DN接收到第二个DN的ack packet确认包加上自身ok,就返回ack packet确认包给FSDataOutputStream对象,标志第一个块 的第一个packeg 的3个副本写完。开始第二个packet写入,如此循环直至第一个块的三个副本写入完毕。
- 然后余下的块依次这样写。
- 当向文件写入数据完成后,Client调用FSDataOutputStream.close()方法,关闭输出流。
- 再调用FileSystem.complete()方法,告诉NN该文件写入成功。
补充:
- 切分block(可以指定两个参数;不知道则使用默认);然后给block分配写入的datanode。
- 以pipeline方式写入;以packet(里面还有chunk数据单元(chunk里又check sum))形式写入;ack机制往上一层一层汇报写完一个chunk(以chunk为单元进行校验)。
文件读流程
- Client调用FileSystem.open(filePath)方法,与NN进行【rpc】通信,返回该文件的部分或者全部的block列表,也就是返回FSDataInputStream对象。
- Client调用FSDataInputStream对象read()方法;
a.与第一个块最近的DN进行read,读取完成后,会check;假如ok,就关闭与当前DN的通信;假如失败,会记录失败块+DN信息,下次不会再读取;那么会去该块的第二个DN地址读取。
b.然后去第二个块的最近的DN上通信读取,check后,关闭通信。
c.假如block列表读取完成后,文件还未结束,就再次FileSystem会从NN获取该文件的下一批次的block列表。
(感觉就是连续的数据流,对于客户端操作是透明无感知的) - Client调用FSDataInputStream.close()方法,关闭输入流。
总体流程图
集群架构
HDFS有主从架构。HDFS集群由一个NameNode组成,它是一个主服务器,管理文件系统名称空间并管理客户机对文件的访问。此外,还有许多datanode,通常每个节点一个,管理连接到它们运行的节点的存储。HDFS公开一个文件系统名称空间,并允许用户数据存储在文件中。在内部,文件被分割成一个或多个块,这些块存储在一组数据节点(datanode)中。NameNode执行文件系统操作,如打开、关闭和重命名文件和目录。它还记录块到datanode的映射。datanode负责服务来自文件系统客户端的读写请求。根据NameNode的指令,datanode还执行块的创建、删除和复制。
上图中
1 个Master(NameNode/NN) 带 N个Slaves(DataNode/DN)
HDFS/YARN/HBase其实都是一样的1个文件会被拆分成多个Block理解为:
blocksize:128M
130M ==> 2个Block: 128M 和 2MNanmenode:
- 1)负责客户端请求的响应
- 2)负责元数据(文件的名称、副本系数、Block存放的DN)的管理
Datenode:
- 1)存储用户的文件对应的数据块(Block)
- 2)要定期向NN发送心跳信息,汇报本身及其所有的block信息,健康状况
一个典型的部署是一台机器运行一个namenade,集群中的其他机器都运行一个DataNode。该体系结构不排除在同一台机器上运行多个DataNode,但在实际部署中却很少出现这种情况。
datanode
存储: 数据块、数据块校验
与NN通信:
a.每隔3s发送心跳包给 nn,我还活者
dfs.heartbeat.interval 3b.每隔一定的时间发生一次 blockreport
dfs.blockreport.intervalMsec 21600000ms=6h
dfs.datanode.directoryscan.interval 21600s=6h
namenode
作用:
- Namespace管理:负责管理文件系统中的树状目录结构以及文件与数据块的映射关系
- 块信息管理:负责管理文件系统中文件的物理块与实际存储位置的映射关系BlocksMap
- 集群信息管理:机架信息,datanode信息
- 集中式缓存管理:从Hadoop2.3 开始,支持datanode将文件缓存到内存中,这部分缓存通过NN集中管理
存储结构:
- 内存: Namespace数据,BlocksMap数据,其他信息
- 文件:
- 已持久化的namespace数据:FsImage
- 未持久化的namespace操作:Edits
启动过程:
- 开启安全模式:不能执行数据修改操作
- 加载fsimage
- 逐个执行所有Edits文件中的每一条操作将操作合并到fsimage,完成后生成一个空的edits文件
- 接收datanode发送来的心跳消息和块信息
- 根据以上信息确定文件系统状态
- 退出安全模式
安全模式(safe mode):文件系统只接受读数据请求,而不接受删除、修改等变更请求
什么情况下进入:NameNode主节点启动时,HDFS进入安全模式
什么时候时候退出:系统达到安全标准时,HDFS退出安全模式
dfs.namenode.safemode.min.datanodes: 最小可用datanode数量
dfs.namenode.safemode.threshold-pct: 副本数达到最小要求的block占系统总block数的百分比
dfs.namenode.safemode.extension: 稳定时间
相关命令:
hdfs dfsadmin -safemode get:查看当前状态
hdfs dfsadmin -safemode enter:进入安全模式
hdfs dfsadmin -safemode leave:强制离开安全模式
hdfs dfsadmin -safemode wait:一直等待直到安全模式结束
SecondaryNamenode
- 存储: fsimage+editlog
- 作用: 定期合并 fsimage+editlog文件作为新的fsimage,推送给NN,
- 简称为checkpoint 检查点
dfs.namenode.checkpoint.period 3600s
dfs.namenode.checkpoint.txns 1000000
为了解决单点故障,只有NN,后来加了一个SNN角色 1小时的备份机制,虽然能够减轻单点故障,但是还会有风险,那60分元数据是恢复不了。
案例:
1 | 1 2 3 4 全备份 fsimage1 |
如图:
1.roll edit
2.传输 fsimage+edits
3.merge
4.传输 fsimage.ckpt to nn
5.回滚 fsimage.ckpt==》fsimage
edit.new==> edit
client写入与 NN+SNN 流程图
HDFS HA
- Datanode: 通过数据冗余保证数据的可用性
- Namenode: 在2.0以前存在SPOF风险,从2.0之后:
- 把name.dir指向NFS(Network File System)
- QJM 方案
HDFS文件类型-列式与行式存储
HDFS 支持任意文件格式主要分为列式与行式
HDFS文件类型-常用文件类型
HDFS文件类型-如何使用?
1 | 在hive中创建表的时候指定文件格式 |
HDFS副本机制
HDFS支持传统的分层文件组织。用户或应用程序可以在这些目录中创建目录并存储文件。文件系统名称空间层次结构与大多数现有文件系统相似;可以创建和删除文件,将文件从一个目录移动到另一个目录,或者重命名文件。
NameNode维护文件系统名称空间。对文件系统名称空间或其属性的任何更改都由NameNode记录。应用程序可以指定由HDFS维护的文件的副本数量。一个文件的副本数量称为该文件的副本因子。这些信息由NameNode存储。
数据副本
HDFS被设计为在大型集群中的机器之间可靠地存储非常大的文件。它以块序列的形式存储每个文件。为了容错,复制文件的块。每个文件的块大小和复制因子都是可配置的。
除了最后一个块之外,文件中的所有块大小都相同。
应用程序可以指定文件的副本数量。副本因子可以在文件创建时指定,以后可以更改。HDFS中的文件只写一次(除了追加和截断之外),并且在任何时候都有一个写入者。
NameNode就块的复制做出所有决定。它定期从集群中的每个datanode接收心跳和数据块报告。接收到心跳表示DataNode正常工作。块报表包含datanode上所有块的列表。
上图代表数据中心,两个机架,黄色代表客户端所在的节点(默认三个副本)
- 第一个副本存放在同client的节点上面;client不是DN,就随机挑选一台磁盘不太慢 CPU不太繁忙的节点。
- 第二个副本存放在不同第一个副本机架的随意一个节点。
- 第三个副本存放在与第二个副本相同机架的另一个节点上。
- 如果只有一个机架,则在不同节点存储;如果高于三个副本则高于三的随意挑选机架和节点。